package com.css.fxfzdzzh.modules.spatialData.repository.impl;

import com.css.fxfzdzzh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzdzzh.modules.spatialData.repository.BoundaryNativeRepository;
import com.css.fxfzdzzh.modules.spatialData.repository.entity.BoundaryEntity;
import com.css.fxfzdzzh.modules.spatialData.viewobjects.BoundaryQueryParams;
import com.css.fxfzdzzh.util.PlatformObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author andy
 * @date 2021-01-26
 */
@Repository
public class BoundaryNativeRepositoryImpl implements BoundaryNativeRepository {

    @Autowired
    public JdbcTemplate jdbcTemplate;

    @Resource
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    private Map<String, List<BoundaryEntity>> parameter2coordinate = new HashMap<>();

    private static final Logger log = LoggerFactory.getLogger(BoundaryNativeRepositoryImpl.class);

    @Override
    public List<BoundaryEntity> listBoundaries(BoundaryQueryParams queryParams) {

        String type = queryParams.getType();
        String level = queryParams.getLevel();
        String name = queryParams.getName();
        String province = queryParams.getProvince();
        String city = queryParams.getCity();
        if ("北京市".equals(city) || "重庆市".equals(city)) city = "市辖区";
        String area = queryParams.getArea();
        String parameter = type + "-" + level + "-" + name + "-" + province + "-" + city + "-" + area;
        if (parameter2coordinate.containsKey(parameter)) return parameter2coordinate.get(parameter);

        StringBuilder sql = new StringBuilder("select * from district_boundary ");
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        List params = new ArrayList();
        if(!PlatformObjectUtils.isEmpty(queryParams.getId())) {
            whereSql.append(" and id = :id");
            params.add(queryParams.getId());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getType())) {
            whereSql.append(" and type = :type");
            params.add(queryParams.getType());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getLevel())) {
            whereSql.append(" and level = :level");
            params.add(queryParams.getLevel());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCode())) {
            whereSql.append(" and code = :code");
            params.add(queryParams.getCode());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getName())) {
            whereSql.append(" and name = :name");
            params.add(queryParams.getName());
        }
        whereSql.append(" and SUBSTRING(code, 1, 4)=(select SUBSTRING(code, 1, 4) from district_boundary where type='1' and level='1' and name='" + queryParams.getCity() + "' and SUBSTRING(code, 1, 2)=(select SUBSTRING(code, 1, 2) from district_boundary where type='1' and level='0' and name='" + queryParams.getProvince() + "'))");

        List<BoundaryEntity> list = jdbcTemplate.query(sql.toString(),new BeanPropertyRowMapper<>(BoundaryEntity.class),
                params.toArray());
        parameter2coordinate.put(parameter, list);
        return list;
    }

    @Override
    public List<BoundaryEntity> newListBoundaries(BoundaryQueryParams queryParams) {
        return null;
    }

    @Override
    public BoundaryEntity getBoundaryEntityByCode(String code) {
        StringBuffer sql = new StringBuffer();
        BoundaryEntity boundaryEntity = new BoundaryEntity();
        if (StringUtils.isNotBlank(code)){
            sql.append("SELECT * FROM district_boundary where 1 =1 and type = '1' ");
            sql.append("and code = ? ");
            boundaryEntity = jdbcTemplate.queryForObject(sql.toString(), new BeanPropertyRowMapper<>(BoundaryEntity.class),code);
        }



        return boundaryEntity;
    }

    /*@Autowired
    private BaseDivisionServiceImpl baseDivisionServiceImpl;

    //ZYT--获取行政区划边界经纬度数组
    @Override
    public List<BoundaryEntity> newListBoundaries(BoundaryQueryParams queryParams) {
        //查询省市县行政区划代码
        DivisionVO divisionVO = new DivisionVO(queryParams.getProvince(),queryParams.getCity(),queryParams.getArea());
        //设置查询的行政区划代码
        if(queryParams.getName().equals(queryParams.getProvince())){//省
            String provinceCode = baseDivisionServiceImpl.findDivisionCodeByName(divisionVO,"1");//省级行政区划代码
            queryParams.setCode(provinceCode);
        }else if(queryParams.getName().equals(queryParams.getCity())){//市
            String cityCode = baseDivisionServiceImpl.findDivisionCodeByName(divisionVO,"2");//市级行政区划代码
            queryParams.setCode(cityCode);
        }else if(queryParams.getName().equals(queryParams.getArea())){//区县
            String areaCode = baseDivisionServiceImpl.findDivisionCodeByName(divisionVO,"3");//区县级行政区划代码
            queryParams.setCode(areaCode);
        }
        //查询行政区划范围
        StringBuilder sql = new StringBuilder("select * from district_boundary ");
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        if(!PlatformObjectUtils.isEmpty(queryParams.getId())) {
            whereSql.append(" and id = :id");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getType())) {
            whereSql.append(" and type = :type");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getLevel())) {
            whereSql.append(" and level = :level");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCode())) {
            whereSql.append(" and code = :code");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getName())) {
            whereSql.append(" and name = :name");
        }
        Query query = this.em.createNativeQuery(sql.append(whereSql).toString(), BoundaryEntity.class);
        if(!PlatformObjectUtils.isEmpty(queryParams.getId())) {
            query.setParameter("id", queryParams.getId());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getType())) {
            query.setParameter("type", queryParams.getType());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getLevel())) {
            query.setParameter("level", queryParams.getLevel());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCode())) {
            query.setParameter("code", queryParams.getCode());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getName())) {
            query.setParameter("name",  queryParams.getName());
        }
        List<BoundaryEntity> list = query.getResultList();
        return list;
    }*/

    @Override
    public String getGeomByArea(String province, String city, String county) {
        StringBuilder sql = new StringBuilder("select coordinate from district_boundary where 1=1");
        if(PlatformObjectUtils.isNotEmpty(county)){
            sql.append(" and name='"+county+"'");
        }else if(PlatformObjectUtils.isNotEmpty(city)){
            if("北京市".equals(province) || "上海市".equals(province) || "重庆市".equals(province) || "天津市".equals(province)){
                sql.append(" and name='"+city+"' and level='2'");
            }else{
                sql.append(" and name='"+city+"' and level='1'");
            }

        }else if(PlatformObjectUtils.isNotEmpty(province)){
            sql.append(" and name='"+province+"' and level='0'");
        }

        String query = jdbcTemplate.queryForObject(sql.toString(), String.class);
        return PlatformObjectUtils.isNotEmpty(query)?query:"";
    }

    @Override
    public String getBoundaryCoordinate(List<String> codeList) {
        String sql = "select st_astext ( st_union ( st_geomfromtext ( coordinate, 4490 ) ), 4490 ) from district_boundary where code IN (:codeList)";
        Map idsMap = new HashMap();
        idsMap.put("codeList", codeList);
        return namedParameterJdbcTemplate.queryForObject(sql.toString(), idsMap, String.class);
    }
}
